import React, { useState, useEffect } from "react";
import { Link } from "react-router-dom";
import _ from "lodash";
import {
  Button,
  Form,
  Select,
  Input,
  TreeSelect,
  Switch,
  Divider,
  Tooltip,
  Icon,
  message,
} from "antd";
import { renderTreeNodes } from "@pkgs/Layout/utils";
import useFormatMessage from "@pkgs/hooks/useFormatMessage";
import { menuData, nameRule } from "../config";
import Editor from "./Editor";
import request from "@pkgs/request";
import api from "@common/api";
import type { DiscoveryTableListType } from "src/pages/Discovery/interface";
import { data2Discover, discoverData } from "./utils";
import "./style.less";

const FormItem = Form.Item;
const { Option } = Select;

const formItemLayout = {
  labelCol: { span: 6 },
  wrapperCol: { span: 14 },
};

const defaultFormData = {
  collect_type: "service",
  timeout: 3,
  rely_ids: "",
  ignore_path: "",
  data_path: "",
  config_path: "",
  version: "#!/bin/bash\n# e.g.\n",
  port: "",
  level: 0,
  strees: [],
  starks: [],
  manuals: [],
  urls: [],
  lvses: [],
};

/**
 * @func 获取发现规则列表
 */
async function getTableLists(discoveryType: string, nid: number) {
  try {
    const res: DiscoveryTableListType[] = await request(
      `${api.discovery}/list?type=${discoveryType}&nid=${nid}&watch_range=review`
    );
    const resData = res.map((item, index) =>
      Object.assign(item, { key: index })
    );
    return resData;
  } catch (e) {
    (e + "").indexOf("null")
      ? message.error("暂无数据!")
      : message.error("请求错误!");
  }
}

const getInitialValues = (initialValues: any) => {
  const data: Record<string, DiscoveryTableListType>[] =
    discoverData(initialValues);
  return _.assignIn({}, defaultFormData, _.cloneDeep(initialValues), {
    prometheus: data,
  });
};

const serviceLevel = [
  { key: 0, value: "无等级" },
  { key: 1, value: "online-0级" },
  { key: 2, value: "online-1级" },
  { key: 3, value: "online-2级" },
  { key: 4, value: "online-3级" },
  { key: 5, value: "offline" },
];

const CollectForm = (props: any) => {
  const intlFmtMsg = useFormatMessage();
  const initialValues = getInitialValues(props.initialValues);
  const { getFieldProps, getFieldDecorator } = props.form;
  const [serviceData, setServiceData] = useState([]);
  const [depService, setDepService] = useState<Array<string>>([]);
  const [prometheusArr, setPrometheusArr] = useState<any>([]);
  const [selectDiscover, setSelectDiscover] = useState<any>([]);

  useEffect(() => {
    if (initialValues.rely_ids !== "") {
      const arr = initialValues.rely_ids.split(",");
      const data: string[] = [];
      arr.forEach((item: number) => {
        request(`${api.collect}?type=service&id=${item}`).then((res) => {
          const resdata = res.name;
          data.push(resdata);
          setDepService(data);
        });
      });
    }
  }, [initialValues.rely_ids]);

  useEffect(() => {
    if (initialValues.nid) {
      // request(`${api.collect}/list?nid=${initialValues.nid}&type=service`)
      request(`${api.collect}/list?type=service`)
        .then((res) => {
          setServiceData(res);
        })
        .catch((err) => {
          console.log(err);
        });
      const data = discoverData(initialValues);
      setPrometheusArr(new Array(data.length).fill(0).map((item, i) => i));
    }
  }, [initialValues.nid]);

  getFieldDecorator("collect_type", {
    initialValue: initialValues.collect_type,
  });

  getFieldDecorator("ignore_path", {
    initialValue: initialValues.ignore_path,
  });

  getFieldDecorator("data_path", {
    initialValue: initialValues.data_path,
  });

  getFieldDecorator("config_path", {
    initialValue: initialValues.config_path,
  });

  getFieldDecorator("version", {
    initialValue: initialValues.version,
  });

  getFieldDecorator("status", {
    initialValue: initialValues.status,
  });

  getFieldDecorator("level", {
    initialValue: initialValues.level,
  });
  getFieldDecorator("strees", {
    initialValue: initialValues.strees,
  });

  if (initialValues.rely_ids) {
    getFieldDecorator("rely_ids", {
      initialValue: depService,
    });
  } else {
    getFieldDecorator("rely_ids", {
      initialValue: undefined,
    });
  }

  const [submitLoading, setSubmitLoading] = useState(false);

  const handleSubmit = (e: any) => {
    e.preventDefault();
    props.form.validateFields((errors: any, values: any) => {
      if (errors) {
        console.error(errors);
        return;
      }
      setSubmitLoading(true);
      if (values["rely_ids"] !== undefined) {
        let rely_ids = values["rely_ids"].join();
        values = { ...values, rely_ids };
      } else {
        let rely_ids = "";
        values = { ...values, rely_ids };
      }
      const cron = values["cron"].trim();
      values = { ...values, cron };
      if (values["prometheus"] !== undefined) {
        const data = data2Discover(values["prometheus"]);
        const { prometheus, ...rest } = values;
        values = { ...rest, ...data };
      }
      props.onSubmit(values).catch(() => {
        setSubmitLoading(false);
      });
    });
  };

  const add = () => {
    if (prometheusArr.indexOf(prometheusArr.length) !== -1) {
      setPrometheusArr([...prometheusArr, prometheusArr.length + 1]);
    } else {
      setPrometheusArr([...prometheusArr, prometheusArr.length]);
    }
  };

  const remove = (item: any) => {
    setPrometheusArr(
      prometheusArr.map((key: any, index: number) => {
        if (key == item) {
          key = null;
        }
        return key;
      })
    );
  };

  const discoverSelect = (event: string) => {
    getTableLists(event, initialValues.nid).then((data) => {
      setSelectDiscover(data);
    });
  };

  useEffect(() => {
    let data: DiscoveryTableListType[] = [];
    if (initialValues.prometheus) {
      initialValues.prometheus.forEach(
        (value: { discoverType: string; data: DiscoveryTableListType }) => {
          data.push(value.data);
        }
      );
    }
    setSelectDiscover(data);
  }, [initialValues.nid]);

  const formItems = prometheusArr.map(
    (item: any, index: number) =>
      item !== null && (
        <FormItem {...formItemLayout} required={false} key={index} label=" ">
          <div className="discover-form-item">
            <FormItem>
              {getFieldDecorator(`prometheus[${item}].discoverType`, {
                initialValue: initialValues.prometheus[item]
                  ? initialValues.prometheus[item].name
                  : null,
              })(
                <Select onChange={discoverSelect}>
                  {menuData.map((key) => (
                    <Option value={key.label} key={key.key}>
                      {key.name}
                    </Option>
                  ))}
                </Select>
              )}
            </FormItem>

            <FormItem>
              {getFieldDecorator(`prometheus[${item}].data.id`, {
                initialValue: initialValues.prometheus[item]
                  ? initialValues.prometheus[item].data.id
                  : null,
              })(
                <Select>
                  {selectDiscover &&
                    selectDiscover.map((key: DiscoveryTableListType) => (
                      <Option value={key.id} key={key.id}>
                        {key.name}
                      </Option>
                    ))}
                </Select>
              )}
            </FormItem>

            <Icon
              className="dynamic-delete-button"
              type="minus-circle-o"
              onClick={() => remove(item)}
            />
          </div>
        </FormItem>
      )
  );

  return (
    <Form layout="horizontal" onSubmit={handleSubmit}>
      <FormItem
        {...formItemLayout}
        label={intlFmtMsg({ id: "collect.common.node" })}
      >
        {getFieldDecorator("nid", {
          initialValue: initialValues.nid,
          rules: [{ required: true, message: "请选择节点！" }],
        })(
          <TreeSelect
            style={{ width: 620 }}
            showSearch
            allowClear
            treeDefaultExpandAll
            treeNodeFilterProp="path"
            treeNodeLabelProp="path"
            dropdownStyle={{ maxHeight: 400, overflow: "auto" }}
          >
            {renderTreeNodes(props.treeData, "treeSelect")}
          </TreeSelect>
        )}
      </FormItem>

      <FormItem
        {...formItemLayout}
        label={intlFmtMsg({ id: "collect.service.name" })}
      >
        <Input
          {...getFieldProps("name", {
            initialValue: initialValues.name,
            rules: [{ required: true, message: "必填项！" }, nameRule],
          })}
          size="default"
          style={{ width: 620 }}
          placeholder={intlFmtMsg({ id: "collect.service.name.placeholder" })}
        />
      </FormItem>

      <FormItem
        {...formItemLayout}
        label={intlFmtMsg({ id: "collect.service.rely_ids" })}
        help={intlFmtMsg({ id: "collect.service.rely_ids.placeholder" })}
      >
        {getFieldDecorator("rely_ids", {
          rules: [{ type: "array" }],
        })(
          <Select mode="multiple" style={{ width: 620 }}>
            {_.map(serviceData, (item: any) => (
              <Option key={item.id} value={item.id}>
                {item.name}
              </Option>
            ))}
          </Select>
        )}
      </FormItem>

      <Divider orientation="left" style={{ padding: "0 10%" }}>
        服务配置
      </Divider>

      <FormItem
        {...formItemLayout}
        label={intlFmtMsg({ id: "collect.service.servicepath" })}
      >
        <Input
          {...getFieldProps("service_path", {
            initialValue: initialValues.service_path,
            rules: [{ required: true, message: "必填项！" }],
          })}
          style={{ width: 620 }}
          placeholder={intlFmtMsg({
            id: "collect.service.servicepath.placeholder",
          })}
        />
      </FormItem>

      <FormItem
        {...formItemLayout}
        label={intlFmtMsg({ id: "collect.service.procpath" })}
      >
        <Input
          {...getFieldProps("proc_path", {
            initialValue: initialValues.proc_path,
            rules: [{ required: true, message: "必填项！" }],
          })}
          style={{ width: 620 }}
          placeholder={intlFmtMsg({
            id: "collect.service.procpath.placeholder",
          })}
        />
      </FormItem>

      <FormItem
        {...formItemLayout}
        label={intlFmtMsg({ id: "collect.service.configpath" })}
      >
        <Input
          {...getFieldProps("config_path", {
            initialValue: initialValues.config_path,
          })}
          style={{ width: 620 }}
          placeholder={intlFmtMsg({
            id: "collect.service.configpath.placeholder",
          })}
        />
      </FormItem>

      <FormItem
        {...formItemLayout}
        label={intlFmtMsg({ id: "collect.service.datapath" })}
      >
        <Input
          {...getFieldProps("data_path", {
            initialValue: initialValues.data_path,
          })}
          style={{ width: 620 }}
          placeholder={intlFmtMsg({
            id: "collect.service.datapath.placeholder",
          })}
        />
      </FormItem>

      <FormItem
        {...formItemLayout}
        label={intlFmtMsg({ id: "collect.service.ignorepath" })}
      >
        <Input
          {...getFieldProps("ignore_path", {
            initialValue: initialValues.ignore_path,
          })}
          style={{ width: 620 }}
          placeholder={intlFmtMsg({
            id: "collect.service.ignorepath.placeholder",
          })}
        />
      </FormItem>

      <FormItem
        {...formItemLayout}
        label={intlFmtMsg({ id: "collect.service.vresion" })}
        help={intlFmtMsg({ id: "collect.service.vresion.placeholder" })}
      >
        {getFieldDecorator("version", {
          initialValue: initialValues.version,
        })(<Editor style={{ width: "100%", height: 200 }} />)}
      </FormItem>

      <FormItem
        {...formItemLayout}
        label={intlFmtMsg({ id: "collect.service.port" })}
      >
        <Input
          {...getFieldProps("port", {
            initialValue: initialValues.port,
          })}
          style={{ width: 620 }}
          placeholder={intlFmtMsg({
            id: "collect.service.port.placeholder",
          })}
        />
      </FormItem>

      <FormItem
        {...formItemLayout}
        label={
          <Tooltip
            placement="topLeft"
            title={
              <span>{intlFmtMsg({ id: "collect.check.cron.prompt" })}</span>
            }
          >
            {intlFmtMsg({ id: "collect.common.step" })}&nbsp;
            <Icon
              type="exclamation-circle"
              style={{
                fontSize: "11px",
                position: "absolute",
                top: "-4px",
              }}
            />
            &nbsp;&nbsp;&nbsp;
          </Tooltip>
        }
      >
        <Input
          {...getFieldProps("cron", {
            initialValue: initialValues.cron,
            rules: [
              {
                required: true,
                type: "string",
                pattern:
                  /^(0|[1-9]|[1-5][0-9])(\s(2[0-3]|1[0-9]|[0-9]|\*))(\s(3[0-1]|[12][0-9]|[0-9]|\*))(\s(1[0-2]|[0-9]|\*))(\s(0|[1-7]|\*))$/,
                message:
                  "字符串按空格切分后长度必须等于5,第一个元素必须是0-59的数字,其余的可以是*也可以是数字,符合cron分时日月周规则",
              },
            ],
          })}
          style={{ width: 620 }}
          placeholder={intlFmtMsg({ id: "collect.check.comment.placeholder" })}
        />
      </FormItem>

      <FormItem
        {...formItemLayout}
        label={intlFmtMsg({ id: "collect.service.level_select" })}
      >
        <Select
          size="default"
          style={{ width: 150 }}
          {...getFieldProps("level", {
            initialValue: initialValues.level,
          })}
        >
          {_.map(serviceLevel, (item: any) => (
            <Option key={item.key} value={item.key}>
              {item.value}
            </Option>
          ))}
        </Select>
      </FormItem>

      <FormItem
        {...formItemLayout}
        label={intlFmtMsg({ id: "collect.check.status" })}
      >
        {getFieldDecorator("status", {
          valuePropName: "checked",
        })(<Switch checkedChildren="开" unCheckedChildren="关" />)}
      </FormItem>

      <Divider orientation="left" style={{ padding: "0 10%" }}>
        业务监控
      </Divider>

      <FormItem label="挂载prometheus采集配置" {...formItemLayout}>
        <Button type="dashed" onClick={add}>
          <Icon type="plus" /> Add field
        </Button>
      </FormItem>
      {formItems}

      <FormItem wrapperCol={{ offset: 6 }} style={{ marginTop: 24 }}>
        <Button type="primary" htmlType="submit" loading={submitLoading}>
          {intlFmtMsg({ id: "form.submit" })}
        </Button>
        <Button style={{ marginLeft: 8 }}>
          <Link
            to={{
              pathname: "/collect/service",
              search: window.location.search,
            }}
          >
            {intlFmtMsg({ id: "form.goback" })}
          </Link>
        </Button>
      </FormItem>
    </Form>
  );
};

export default Form.create()(CollectForm);
